package org.restorator.service.impl;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;

import org.restorator.dao.base.UserDao;
import org.restorator.dao.tx.TransactionManager;
import org.restorator.dao.tx.TransactionManagerJdbc;
import org.restorator.dao.tx.TxManagerJdbc;
import org.restorator.entity.Order;
import org.restorator.entity.Table;
import org.restorator.entity.User;
import org.restorator.entity.dto.TableDto;
import org.restorator.entity.dto.UserDto;
import org.restorator.exception.ServiceException;
import org.restorator.exception.TransactionException;
import org.restorator.service.UserService;
import org.restorator.dao.implement.UserDaoImpl;
import org.restorator.utill.GeneralUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserServiceImpl implements UserService {

	private UserDao userDao = new UserDaoImpl();
	private TransactionManager tx = TxManagerJdbc.INSTANCE;
    private static Logger logger = LoggerFactory.getLogger(GeneralUtil.getClassName());


    @Override
	public User getUserByLoginAndPass(final String password, final String login) throws ServiceException {
		return tx.doInTran(new Callable<User>() {
			public User call() throws Exception {
				return userDao.getUserByLoginAndPass(password, login);
			}
		});
	}

    public User get(final Integer integer) throws ServiceException {
		return tx.doInTran(new Callable<User>() {
			public User call() throws Exception {
				return userDao.get(integer);
			}	
		});
	}
	
	public Integer save(final User user) throws ServiceException {
		return tx.doInTran(new Callable<Integer>() {
			public Integer call() throws Exception {
				return userDao.save(user);
			}	
		});
	}
	
	public void update(final User user) throws ServiceException {
        logger.debug("update user: {}", user);
		tx.doInTran(new Callable<User>() {
			public User call() throws Exception {
				return userDao.update(user);
			}	
		});
	}

    @Override
    public Integer save(final User entity, Object... arg) throws ServiceException {
        return tx.doInTran(new Callable<Integer>() {
            public Integer call() throws Exception {

                return userDao.save(entity);
            }
        });
    }

    public void delete(final User user) throws ServiceException {
		tx.doInTran(new Callable<User>() {
			public User call() throws Exception {
				userDao.delete(user);
				return null;
			}	
		});
	}
	
	public List<User> getAll() throws ServiceException {
        return tx.doInTran(new Callable<List<User>>() {
            public List<User> call() throws Exception {
                return userDao.getAll();
            }
        });
    }

    /**
     *
     * @param key
     * @return
     * @throws ServiceException
     */
    @Override
    public User getUserByKey(final String key) throws ServiceException {
        logger.debug("get user by key - {}", key);
        return tx.doInTran(new Callable<User>() {

            @Override
            public User call() throws Exception {
                return userDao.getUserByKey(key);
            }
        });
    }


    @Override
    public UserDto toDto(User actual) {
        UserDto d = new UserDto();
        d.setName(actual.getLogin());
        return d;
    }

    @Override
    public Collection<UserDto> toDto(Collection<User> actual) {
//        logger.debug("FromDTO actual = {}", actual);
        ArrayList<UserDto> list = new ArrayList<>();
        for(User t : actual) {
            list.add(toDto(t));
        }
//        logger.debug("FromDTO list = {}", actual);
        return list;
    }

    @Override
    public User fromDto(UserDto dto) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Collection<User> fromDto(Collection<UserDto> dtos) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
